<?PHP
	/************************************************************************
	*       This file, in addition to all other parts of X7 Chat are        *
	*                   Copyright 2003-2007 by Tim Chamness.                *
	* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
	* Version:          X7 Chat 3.0.0-A2                                    *
	* Release Date:     October 20, 2007                                    *
	* Author:           Tim Chamness                                        *
	* Copyright:        2003-2007 by Tim Chamness                           *
	* Website:          http://www.x7chat.com/                              *
	* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
	* X7 Chat 3 is free software; you can redistribute it and/or modify     *
	* it under the terms of the GNU General Public License as published by  *
	* the Free Software Foundation; either version 3 of the License, or     *
	* (at your option) any later version.                                   *
	*                                                                       *
	* X7 Chat 3 is distributed in the hope that it will be useful, but      *
	* WITHOUT ANY WARRANTY; without even the implied warranty of            *
	* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
	* General Public License for more details.                              *
	*                                                                       *
	* You should have received a copy of the GNU General Public License     *
	* along with this program.  If not, see <http://www.gnu.org/licenses/>. *
	*                                                                       *
	* Additional Terms, compatible with Section 7 of the GNU GPL v3,        *
	* apply to X7 Chat 3 and all X7 Chat 3 files, including this one.       *
	* You should have received a copy of these Additional Terms in the      *
	* file docs/COPYING.ADDITIONAL_TERMS.  If you did not receive a copy    *
	* please visit <http://www.x7chat.com/COPYING.ADDITIONAL_TERMS/>.       *
	************************************************************************/

	/**
	 * This handles information about the user who is currently executing the script.
	 * It also handles things like login and logout.
	 */
	class lib_session {
		public $user = null;
		public $session_string;
		public $time;
		public $login_error_message = '';

		function __construct(){
			global $settings;
			
			$this->time = time();
	
			if(isset($_GET['logout'])){
				unset($_GET['x7session']);
				$_GET['act'] = 'login';
			}

			$un = x7in::get($_POST,'lgnusername','f-n');
			$up = x7in::get($_POST,'lgnpassword','f-n');
			if(!empty($un)){
				// Login test
				$pwc = check_password($un,$up);
				$ldc = new lib_user($un);

				if($pwc === true){
					// Login ok
					if($ldc->is_valid()){
						// Remote and local checks pass 100%
						$this->user = $ldc;
					}else{
						// Remote check ok but no local data exists
						$this->user = lib_user_extended::create_user_account($un,$up,2,array('ip'=>$_SERVER['REMOTE_ADDR']),true);
					}
					
				}elseif($pwc === null){
					// Record does not exist, see if we can create a guest account

					// Cleanup old guest accounts if necessary
					if($ldc->is_valid()){
						// See if the password matches (probably a refresh)
						if($ldc->data_cache['password'] == sha1($up)){
							// Password matches, allow use of this account if it is activated
							if($ldc->data_cache['activation_code'] == 0)
								$this->user = $ldc;
							else{
								if(strlen($ldc->data_cache['activation_code']) == 40)
									$this->login_error_message = $GLOBALS['LANG']->lang_intro->account_inactive;
								else
									$this->login_error_message = $GLOBALS['LANG']->lang_intro->account_inactive_admin;
							}
						}elseif($ldc->data_cache['group'] == 3 && ($GLOBALS['CACHE']->gettime("private_messages/{$ldc->data_cache['uid']}") < $this->time-$settings['online_expire_seconds'])){
							// This account can be used, clear it out
							$ldc->remove();
							$ldc->data_cache = null;
						}
					}

					if(!$ldc->is_valid() && $settings['allow_guests']){
						// Username is not in use, create a guest account

						// Generate a password if necessary
						if(empty($up)) $up = substr(md5(rand(0,500)*microtime(true)),0,$settings['password_max_length']-1);
						
						// Check username for validity
						$check_uname = lib_user_extended::validate_username($un);
						if(!empty($check_uname))
							$this->login_error_message = $check_uname;
						
						// Validate password
						$check_pword = lib_user_extended::validate_password($up);
						if(!empty($check_pword))
							$this->login_error_message = $check_pword;

						if(empty($this->login_error_message)){
							$uid = $GLOBALS['DATABASE']->table_next_id('users');
							$new_user = new lib_user($uid);
							
							$new_user->data_cache = array(	
											'uid'=>$uid,
											'name'=>$un,
											'group'=>3,
											'password'=>sha1($up),
											'ip'=>$_SERVER['REMOTE_ADDR'],
											'profile'=>array(),
											'email'=>"guest$uid@localhost",
											'buddies'=>array(),
											'ignore'=>array(),
											'activation_code'=>0,
											'reset_code'=>'',
											'status'=>'',
											'settings'=>array('styles'=>array('font'=>'','size'=>'','color'=>''),'show_timestamps'=>1,'show_smilies'=>1,'play_sounds'=>1,'show_styles'=>1,'hide_email'=>1),
											'perms'=>array());
											
							$new_user->commit_changes();
							
							$this->user = $new_user;
						}
						
					}
				}

				if($this->user !== null){
					// Login ok
					$this->create_session($this->user);
					$_GET['x7session'] = base64_encode("{$this->user->data_cache['uid']};".$this->user->data_cache['session']);

					// See if this user's ip address has changed since the previous login
					if(!isset($this->user->data_cache['ip']) || $this->user->data_cache['ip'] != $_SERVER['REMOTE_ADDR']){
						$this->user->commit_changes(array('ip'=>$_SERVER['REMOTE_ADDR']));
					}
				}else{
					// Login failed
					$_GET['act'] = 'login';
					unset($_GET['x7session']);
					if(empty($this->login_error_message))
						$this->login_error_message = $GLOBALS['LANG']->lang_intro->login_error_password;
				}
			}

			if(isset($_GET['x7session'])){
				$cook = explode(";",base64_decode($_GET['x7session']));
				
				if($this->user === null)
					$dtest = new lib_user($cook[0]);
				else
					$dtest = $this->user;
				
				if($dtest->is_valid()){
					if($dtest->data_cache['session'] == $cook[1]){
						if($dtest->data_cache['activation_code'] == 0){
							$this->user = $dtest;
							$this->session_string = "&x7session=".$_GET['x7session'];
							
							$this->theme = $settings['default_theme'];
							$this->language = $settings['default_lang'];
						}else{
							$_GET['act'] = 'login';
							unset($_GET['x7session']);
							if(strlen($dtest->data_cache['activation_code']) == 40)
								$this->login_error_message = $GLOBALS['LANG']->lang_intro->account_inactive;
							else
								$this->login_error_message = $GLOBALS['LANG']->lang_intro->account_inactive_admin;
						}
					}else{
						$_GET['act'] = 'login';
						unset($_GET['x7session']);
						$this->login_error_message = $GLOBALS['LANG']->lang_intro->login_error_password;
					}
				}
			}
		}
		
		/**
		 * Checks to see if the user is banned from the server
		 * 
		 * @return True if the user is banned, false if they are not
		 */
		public function is_banned(){
			global $settings;
			
			// Check IP Bans
			$ip_addr = explode(".",$_SERVER['REMOTE_ADDR']);
			$ip[0] = $ip_addr[0].".".$ip_addr[1].".".$ip_addr[2].".".$ip_addr[3];
			$ip[1] = $ip_addr[0].".".$ip_addr[1].".".$ip_addr[2].".*";
			$ip[2] = $ip_addr[0].".".$ip_addr[1].".*.*";
			$ip[3] = $ip_addr[0].".*.*.*";
			$ban = false;
			
			// TODO: Make this more efficient and implement username banning.
			foreach($settings['bans'] as $baninfo){
				if($baninfo['end'] == 0 || $baninfo['end'] > $this->time){
					if(isset($baninfo['ip']) && in_array($baninfo['ip'],$ip)){
						return true;
					}
				}
			}

			return false;
		}
		
		/**
		 * Get the name of the theme that should be used to
		 * display the chatroom.
		 *
		 * @return The name of the theme to use
		 */
		public function get_theme(){
			global $settings;
			return $settings['default_theme'];
		}
		
		/**
		 * Get the language that should be used to display the chatroom
		 *
		 * @return The name of the language to use
		 */
		public function get_language(){
			global $settings;
			return $settings['default_lang'];
		}
		
		private function create_session($user){
			$session_id = sha1(mt_rand(100,900)*(mt_rand(5,10)+microtime_float()));
			$user->data_cache['session'] = $session_id;
			$user->commit_changes();
		}

	}
?>